/*
 * @Author: wangjun haodreams@163.com
 * @Date: 2024-05-09 13:27:28
 * @LastEditors: wangjun haodreams@163.com
 * @LastEditTime: 2024-05-17 08:59:56
 * @FilePath: \golib\memdb\ast_sql.go
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
package memdb

// SelectStmt based on http://www.h2database.com/html/grammar.html
type SelectStmt struct {
	Select  string       `parser:"@('SELECT') "`
	Fields  []*Field     `parser:"@@ ( ',' @@ )*"`
	From    string       `parser:"'FROM' @Ident"`
	Where   []*Condition `parser:"( 'WHERE' @@  ( 'AND' @@ )*)?"`
	GroupBy *GroupBy     `parser:"('GROUP' 'BY' (@@)*)?"`
	FillBy  *FillBy      `parser:"('FILL' 'BY' (@@)*)?"`
	OrderBy *OrderBy     `parser:"('ORDER' 'BY' (@@)*)?"`
}

//@Ident a-z A-Z 0-9 _ * 任意字符
type GroupBy struct {
	Name []string `parser:"@Ident ( ',' @Ident )*"`
}

type OrderBy struct {
	Name string `parser:"@Ident"`
	DESC bool   `parser:"[ @'DESC' ]"`
}

type FillBy struct {
	Name []string  `parser:"@Ident ( ',' @Ident )*"`
	Vals []float64 `parser:"'(' @Number ( ',' @Number )* ')'"`
}

type Fields struct {
	Field []*Field `parser:"@@ ( ',' @@ )*"`
}

type Field struct {
	Name []string `parser:"@Ident ('(' @Ident ')')*"`
	//Name1 string `|`
	As string `parser:"( 'AS' @Ident )?"`
}

type Condition struct {
	Name    string   `parser:"@Ident"`
	CondRHS *CondRHS `parser:"@@?"`
}

type CondRHS struct {
	Compare *Compare ` parser:" @@"`
	Is      *Is      `parser:"| 'IS' @@"`
	In      *Array   `parser:"| 'IN' '(' @@ ')'"`
	Like    *Like    `parser:"| 'LIKE' @@"`
}

//数学函数
type Math struct {
	Name     string  `parser:"@Ident"`
	Operator string  `parser:"@( '+' | '-' | '*' | '/' | '%' )"`
	Number   float64 `parser:"@Number"`
}

type Compare struct {
	Operator string   `parser:"@( '<>' | '<=' | '>=' | '=' | '<' | '>' | '!=' )"`
	String   *string  `parser:"(@String"`
	Math     *Math    ` parser:" | @@"` //数学表达式
	Number   *float64 `parser:" | @Number)"`
}

type Like struct {
	Not     bool   `parser:"[ @'NOT' ]"`
	Operand string `parser:"@String"`
}

type Is struct {
	Not  bool `parser:"[ @'NOT' ]"`
	Null bool ` parser:"@'NULL'"`
}

type Array struct {
	StrArray []string  `parser:"@String ( ',' @String )* "`
	NumArray []float64 `parser:"| @Number ( ',' @Number )* "`
}
